package com.zzb.projectfactory.framework.query;

import org.apache.commons.beanutils.BeanUtils;
import org.joda.time.DateTime;
import org.springframework.jdbc.core.RowMapper;

import javax.persistence.Column;
import javax.persistence.Transient;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;

/**
 * 通过注解@Column映射字段
 * Created by zhangzhenbin on 2016/12/13.
 */
public class AnnotationColumnRowMapper<T> implements RowMapper<T> {

    /**获取T的基本类型*/
    private Class<T> clazz;

    public AnnotationColumnRowMapper(Class<T> clazz) {
        this.clazz = clazz;
    }

    @Override
    public T mapRow(ResultSet rs, int rowNum) throws SQLException {
        Class<T> tClazz = clazz;
        T t;
        try {
            t = tClazz.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
            throw new SQLException("返回对象实例化失败，请确认有默认构造方法",e);
        }
        Field[] declaredFields = ReflectionUtils.getAllDeclaredFields(clazz);

        for (Field declaredField : declaredFields) {
            Transient aTransient = declaredField.getAnnotation(Transient.class);
            if(aTransient != null) continue;
            Class<?> type = declaredField.getType();
            String fieldName = declaredField.getName();
            String columnName = fieldName;//数据库字段名默认是属性名
            //如果有定义@Column注解，则使用注解定义的column.name()
            Column column = declaredField.getAnnotation(Column.class);
            if( column != null){
                columnName = column.name();
            }

            try {
                if(type.equals(BigDecimal.class)){
                    BeanUtils.setProperty(t,fieldName,rs.getBigDecimal(columnName));
                } else if (type.equals(String.class)) {
                    BeanUtils.setProperty(t,fieldName,rs.getString(columnName));
                } else if (type.equals(Integer.class) || type.equals(int.class)) {
                    BeanUtils.setProperty(t,fieldName,rs.getInt(columnName));
                } else if (type.equals(Long.class) || type.equals(long.class)){
                    BeanUtils.setProperty(t,fieldName,rs.getLong(columnName));
                } else if (type.equals(Double.class)  || type.equals(double.class)){
                    BeanUtils.setProperty(t,fieldName,rs.getDouble(columnName));
                } else if (type.equals(Date.class)){
                    BeanUtils.setProperty(t,fieldName, DateTime.parse(rs.getTimestamp(columnName).toLocalDateTime().toString()).toDate());
                } else if (type.equals(Boolean.class) || type.equals(boolean.class)){
                    BeanUtils.setProperty(t,fieldName,rs.getBoolean(columnName));
                } else if (type.equals(Byte.class) || type.equals(byte.class)){
                    BeanUtils.setProperty(t,fieldName,rs.getByte(columnName));
                } else if (type.equals(Timestamp.class)){
                    BeanUtils.setProperty(t,fieldName,rs.getTimestamp(columnName));
                } else {
                    throw new Exception("字段类型["+type.getSimpleName()+"]对应失败，请联系作者");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

        return t;
    }
}
